package jeconbond.experiment.market.resourcerelations.process;

import jeconbond.experiment.market.equilibrium.process.MooreExperimentContext;
import jeconbond.experiment.market.resourcerelations.ResourceRelationExperimentSettings;
import jeconbond.automata.behaviour.antstrat.IFeramonStorrage;
import jeconbond.economic.resources.ResourceUtils;

import java.util.List;
import java.util.ArrayList;

import laboratoryQ.BaseUtils;

public abstract class BaseResourceRelationExperimentContext extends MooreExperimentContext implements IResourceRelationExperimentContext {
	private List<IFeramonStorrage> feramonStorragesList = new ArrayList<IFeramonStorrage>();
	private int goalPosition = 0;
	protected double[][] abstractProbabSums;

	/**
	 * 4 factory
	 */
	public BaseResourceRelationExperimentContext() {}

	public BaseResourceRelationExperimentContext(ResourceRelationExperimentSettings experimentSettings) {
		super(experimentSettings);

		if (experimentSettings.getCommoditiesAbstractGroupsPower() > 0.0) {
			double[][] dependProbabsMatrix = ResourceUtils.depMatrixFromGroups(
					experimentSettings.getCommoditiesAbstractGroupsPower(),
					experimentSettings.getCommoditiesAbstractGroups()
			);
			abstractProbabSums = probabs2prSums(dependProbabsMatrix);
		}
	}

	@Override
	public ResourceRelationExperimentSettings getExperimentSettings() {
		return (ResourceRelationExperimentSettings) super.getExperimentSettings();
	}

	@Override
	public List<IFeramonStorrage> getFeramonStorragesList() {
		return feramonStorragesList;
	}

	@Override
	public int nextGoalPosition() {
		int result = goalPosition++;
		ResourceRelationExperimentSettings experimentSettings = getExperimentSettings();
		if (result >= experimentSettings.resources.length) {
			result = BaseUtils.randomInt(
					getRandom(), experimentSettings.resources.length
			);
		}
		return result;
	}

	private double[][] probabs2prSums(double[][] dependProbabsMatrix) {
		int n = dependProbabsMatrix.length;
		double[][] result = new double[n][];
		for (int i = 0; i < n; i++) {
			double sum = 0.0;
			double[] curs = dependProbabsMatrix[i];
			double[] curd = new double[curs.length];
			for (int j = 0; j < curs.length; j++) {
				sum += curs[j];
				curd[j] = sum;
			}
			result[i] = curd;
		}
		return result;
	}
}
